package com.estar.integaration.Controller.MoneyController;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.estar.integaration.DS.DirectDFS;
import com.estar.integaration.DS.Graph;
import com.estar.integaration.DS.Vertex;
import com.estar.integaration.Parser.MMParser;
import com.estar.integaration.Parser.MaterialCompositionParse;
import com.estar.integaration.Parser.MaterialGroupParse;
import com.estar.integaration.Parser.MaterialMoneyParse;
import com.estar.integaration.Util.ExcelReader.MaterialListItem;
import com.estar.integaration.Util.StringUtil;
import com.estar.integaration.entity.NoSQL.Res;
import com.estar.integaration.entity.moneyEntity.MaterialGroupMoney;
import com.estar.integaration.entity.moneyEntity.MaterialMoney;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * Author: YJL
 * Date: 2022/1/21 15:41
 **/

@RestController
@RequestMapping("/inventory-analy")
public class InventoryAnalyse {

  @Value("${spring.profiles.active}")
  private String mEnvironment;

  String folderAddress = null;

  List<MaterialMoney> outputList = new ArrayList<>();

  @GetMapping("/analyse-data")
  @ResponseBody
  public Res analyseData()  {

    folderAddress = mEnvironment.equals("dev") ? "D:\\SCM_file\\inventoryFile\\" : "/root/excel/inventoryFile/";
//    folderAddress = "/root/excel/inventoryFile/";
    //处理文件
    //Excel转成实体类
    MaterialCompositionParse materialCompositionParse = new MaterialCompositionParse();
    MaterialGroupParse materialGroupParse = new MaterialGroupParse();
    MaterialMoneyParse materialMoneyParse = new MaterialMoneyParse();

    List<List<Integer>> materialRelationShipList = new LinkedList<>();//点关系的List 1(a)-->2(b)-->3(c)
    List<List<String>> materialCodeRelationShipList = new LinkedList<>();//点关系的List a -> b -> c
    List<Vertex[]> materialIndexList = new LinkedList<>();//每个文件的点的Array [a,b,c] 用123找abc\
    File outFile = new File(folderAddress +  "out.txt");

    /**
      保险杠 机架 保险杠 {0，1，2}
    保险杠
     机架
     保险杠


     **/
//    try {
//      PrintStream stream = new PrintStream(outFile);
//      System.setOut(stream);
//    }catch (FileNotFoundException e){
//      e.printStackTrace();
//    }

    File folder = new File(folderAddress + "materialList");

//    List<MaterialGroupMoney> materialGroupMoneyList = materialGroupParse.parseExcel(getinventoryAgeFiles(folderAddress,"productionShop"));
//    HashMap<String,Integer> cMaterialGroupHashMap = materialGroupParse.getMaterialCodeProductRoomHashMap(materialGroupMoneyList);//物料号和组
    List<MaterialGroupMoney> materialGroupMoneyList = null;
    HashMap<String,Integer> cMaterialGroupHashMap = null;

    if(folder.isDirectory()){
      File[] fileArray = folder.listFiles();
      File fileName = null;
      List<MaterialListItem> excelContents = new ArrayList<>();
      //所有物料清单Excel文件的List
//      List<List<Object>> excelContents = new ArrayList<>();
      for (int i = 0; i < fileArray.length ; i++){
        fileName = fileArray[i];
        String name = fileName.getAbsolutePath();
        excelContents.addAll(materialCompositionParse.parseeasyExcel2Content(name));
      }
      //        List<MaterialComposition> materialCompositionList = materialCompositionParse.parseExcel(name);
      System.out.println(excelContents.size());
//      excelContents = elimination(excelContents);//取消去重
      LinkedList<LinkedList<Integer>> indexListMatrix = materialCompositionParse.parseContent2LinkedListMatrix(excelContents);
      //再次垃圾回收
      excelContents.clear();
      excelContents = null;

//        printIndex(indexMatrix);
//      List<String> matrixEdge = materialCompositionParse.getMatrixEdgeList();
//        printMatrixEdge(matrixEdge);
//        printMatrix(matrixEdge,matrix);
      //DFS输出邻接矩阵

      materialGroupMoneyList = materialGroupParse.parseExcel(getinventoryAgeFiles(folderAddress,"productionShop"));

      cMaterialGroupHashMap = materialGroupParse.getMaterialCodeProductRoomHashMap(materialGroupMoneyList);//物料号和组
      materialGroupMoneyList.clear();
      materialGroupMoneyList = null;


      System.out.println("深搜输出");
      Integer[][] indexMatrix = null;
      Graph g = new Graph(indexListMatrix.size(),indexMatrix,materialCompositionParse.getVertexList(),indexListMatrix);
      DirectDFS directDFS = new DirectDFS(g,cMaterialGroupHashMap);
      //得到此文件的全部结果
      List<List<Integer>> aList = directDFS.DFSRun(g);
      List<List<String>> materialCodeList = directDFS.getMaterialCodeRelationShipFromMaterialCodeIndex(aList,g.getVertexs());

      materialCodeRelationShipList.addAll(materialCodeList);
      materialIndexList.add(g.getVertexs());
    }


    List<MaterialMoney> materialMoneyList = materialMoneyParse.parseExcel(getinventoryAgeFiles(folderAddress,"inventoryAge"));
    HashMap<String,MaterialMoney> mmCodeMMHashMap = materialMoneyParse.getMCodeMM(materialMoneyList);//物料号和物料账期的Hash

    //解析出结果List
    MMParser mmParser = new MMParser(materialCodeRelationShipList,materialIndexList,cMaterialGroupHashMap,mmCodeMMHashMap);
    mmParser.getInventoryMaterialList();
    System.out.println("------------输出---------------");


    /**
     * 0 二组共担
     * 1 四组共担
     * 2 一组
     * 3 二组
     * 4 暂不处理
     */
    /**
    String[] groups = {"一组","二组","二组共担","四组共担","其他"};
    for(int i = 0; i < resList.size() ; i++){
      List<MaterialMoney> tmpList = resList.get(i);
      tmpList = tmpList.stream().distinct().collect(Collectors.toList());//去重
      System.out.println("-------------------------------" + groups[i] + "---------------------------------------");
//      tmpList.forEach(m -> System.out.println(m));
      System.out.println(tmpList.size());
    }**/
    ArrayList<MaterialMoney> materialMoneyArrayList = new ArrayList<>(mmCodeMMHashMap.values());
    outputList = (List<MaterialMoney>) materialMoneyArrayList.clone();

    return new Res("20000",new Gson().toJson(materialMoneyArrayList));
  }


  /**
   *
   * @param keyExtractor
   * @param <T>
   * @return
   */
  public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Map<Object,Boolean> seen = new ConcurrentHashMap<>();
    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
  }

  /**
   * 去重
   * @param contents
   * @return
   */
  private List<List<Object>> elimination(List<List<Object>> contents){
    return contents.stream().filter(distinctByKey(b -> b.get(9))).collect(Collectors.toList());
  }

  @GetMapping("/downloadExcel")
  @ResponseBody
  public void downLoadExcel(HttpServletResponse response){
    ExcelWriter excelWriter = ExcelUtil.getWriter();
    excelWriter.addHeaderAlias("baseMaterialCode","物料编码");
    excelWriter.addHeaderAlias("materialName","物料名称");
    excelWriter.addHeaderAlias("spec","规格型号");
    excelWriter.addHeaderAlias("unit","库存单位");
    excelWriter.addHeaderAlias("quantity","数量");
    excelWriter.addHeaderAlias("allMoney","参考金额");
    excelWriter.addHeaderAlias("brand","品牌");
    excelWriter.addHeaderAlias("group","组别");
    excelWriter.addHeaderAlias("stepOneMoney","0-89");
    excelWriter.addHeaderAlias("stepTwoMoney","90-159");
    excelWriter.addHeaderAlias("stepThreeMoney","160-239");
    excelWriter.addHeaderAlias("stepFourMoney","240-360");
    excelWriter.write(outputList,true);
    response.setContentType("application/vnd.ms-excel;charset=utf-8");
    String name = StringUtil.toUtf8String("库存详情");
    response.setHeader("Content-Disposition","attachment;filename="+name+".xls");
    ServletOutputStream out = null;
    try {
      out = response.getOutputStream();
      excelWriter.flush(out,true);
    } catch (IOException e) {
      e.printStackTrace();
    }finally {
      excelWriter.close();
    }
    try {
      out.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 拿到库存账龄文件地址
   * @return
   */
  private String getinventoryAgeFiles(String basePath,String folderName){
    String allPath = basePath + folderName;
    File folder = new File(allPath);
    File[] files = folder.listFiles();
    File file = null;
    if(files.length == 1){
     file = files[0];
    }
    return file.getAbsolutePath();
  }





}
